﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using YAPL.Language.Ast.Utils;

namespace YAPL.Language.Ast {
	/// <summary>
	/// Represents block of code inside some method or inside another block.
	/// Blocks have their own scope with local variables, etc.
	/// </summary>
	public class CodeBlockExpression : Expression {
		private readonly List<Expression> _expressions;

		public CodeBlockExpression(ExpressionType nodeType, Type type, List<Expression> expressions)
			: base(nodeType, type) {
			_expressions = expressions;
		}

		public CodeBlockExpression(ExpressionType nodeType, Type type, bool canRead, bool canWrite, List<Expression> expressions)
			: base(nodeType, type, canRead, canWrite) {
			_expressions = expressions;
		}

		[Descendant(AstVisit.AfterCurrent)]
		public IList<Expression> Expressions {
			get { return _expressions; }
		}

		public override bool NodeEquals(Expression other) {
			if (other is CodeBlockExpression) {
				var otherExprCount = (other as CodeBlockExpression)._expressions.Count;
				return _expressions.Count.Equals(otherExprCount);
			}
			return false;
		}

		public override bool RewriteChild(Expression child, Expression newExpression) {
			var rewritten = false;
			for (var i = 0; i<_expressions.Count; i++) {
				if (ReferenceEquals(_expressions[i],child)) {
					_expressions[i] = newExpression;
					rewritten = true;
				}
			}
			return rewritten;
		}
	}
}
